#include<mysql_connection.h>
#include<mysql_driver.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace sql;
#include<fstream>
#include <iostream>
#include<list>
#include<vector>
#include<unordered_map>
#include<fstream>
#include<sstream>
#include<memory>
#include<regex>
#include<set>
using std::vector;
using std::set;
using std::pair;
using std::regex;
using std::regex_replace;
using std::ifstream;
using std::ofstream;
using std::unique_ptr;
using std::stringstream;
using std::ifstream;
using std::ofstream;
using std::unordered_map;
using std::list;
using std::vector;
using std::string;
using std::cin;
using std::cout;
using std::endl;
void string_Filter(string& str)
{
    regex pattern("'");
    regex_replace(str,pattern,"\"");
    regex pattern2("\\\\");
    regex_replace(str,pattern2,"\\\\");
}
/// @brief 读取网页库到容器中
/// @param webpage_path 网页库date路径
/// @return 网页库 <<网页库对象list>>
void read_webpage(string webpage_path,vector<vector<string>>& webpage)
{
ifstream ifs;
ifs.open(webpage_path,std::ios::in);
if(!ifs.is_open())
{
    perror("open webpage");
    return  ;
}
string line;
regex htmltages("<[^>]*>");
string id,title,link,description;
while(getline(ifs,line))
{
    int temp1=0;
   
    if(temp1=(line.find("<docid>",0))!=std::string::npos)
    {
        id=regex_replace(line,htmltages,"");
    }
    else  if(temp1=(line.find("<title>",0))!=std::string::npos)
    {
        
        title=regex_replace(line,htmltages,"");
    }
    else  if(temp1=(line.find("<link>",0))!=std::string::npos)
    {
      
        link=regex_replace(line,htmltages,"");
    }
    else  if(temp1=(line.find("<description>",0))!=std::string::npos)
    {
       
        description=regex_replace(line,htmltages,"");
    }
    if(id.size()!=0&&title.size()!=0&&link.size()!=0&&description.size()!=0)
    {
        vector<string>temp_list;
        temp_list.push_back(id);
        temp_list.push_back(title); 
        temp_list.push_back(link);
        temp_list.push_back(description);
        webpage.push_back(temp_list);
        id.clear();
        title.clear();
        link.clear();
        description.clear();
    }
}
ifs.close();
return ;
}
/// @brief string 按空格分割成vector<string>
/// @param line 字符串
/// @param vec 容器
void string_vector(string line,vector<string>& vec)
{
    stringstream ss(line);
    string temp_str;
    while(getline(ss,temp_str,' '))
    {
        vec.push_back(temp_str);
    }
}
/// @brief 读取倒序索引库
/// @param invert_index_path  路径 
/// @return 索引库容器
void read_invert_index(string invert_index_path,unordered_map<string,unordered_map<int,double>>&invert_index)
{
ifstream ifs;
ifs.open(invert_index_path);
if(!ifs.is_open())
{
    perror("open invert_index");
    return ;
}
string line;
while(getline(ifs,line))
{
if(line.size()==0)
continue;
vector<string>temp_vec;
unordered_map<int,double> temp_umap;
string_vector(line,temp_vec);
for(size_t i=1;i<temp_vec.size();i=i+2)
{
stringstream geek(temp_vec[i]);
int id=0;
geek>>id;
stringstream geek2(temp_vec[i+1]);
double weight=0;
geek2>>weight;
temp_umap.emplace(id,weight);
}
invert_index.emplace(temp_vec[0],temp_umap);
}
ifs.close();
return;
}
/// @brief 读取字典库
/// @param Dictionary_index_path 中文字典库
/// @param Dictionary_index_path2 英文字典库
/// @return 字典容器
void read_Dictionary_index(string Dictionary_index_path,string Dictionary_index_path2,unordered_map<string,int>&Dictionary_index)
{
ifstream ifs1;
ifs1.open(Dictionary_index_path);
if(!ifs1.is_open())
{
    perror("open Dictionary_index");
    return ;
}
string line;
while(getline(ifs1,line))
{
vector<string> temp_vec;
string_vector(line,temp_vec);
stringstream geek2(temp_vec[1]);
int Frequency=0;
geek2>>Frequency;
Dictionary_index.emplace(temp_vec[0],Frequency);
}
ifs1.close();
ifstream ifs2;
ifs2.open(Dictionary_index_path2);
if(!ifs2.is_open())
{
    perror("open Dictionary_index2");
    return;
}
line.clear();
while(getline(ifs2,line))
{
vector<string> temp_vec;
string_vector(line,temp_vec);
stringstream geek2(temp_vec[1]);
int Frequency=0;
geek2>>Frequency;
Dictionary_index.emplace(temp_vec[0],Frequency);
}
ifs2.close();
return;
}
/// @brief 读取索引库
/// @param Unit_index_path 中文索引库
/// @param Unit_index_path2 英文索引库
/// @return 存储容器
void read_Unit_index(string Unit_index_path ,string Unit_index_path2,unordered_map<string,vector<int>>& Unit_index)
{
ifstream ifs1;
ifs1.open(Unit_index_path);
if(!ifs1.is_open())
{
    perror("open Unit_index");
    return ;
}
string line;
while(getline(ifs1,line))
{
vector<string>temp_vec;
vector<int>temp_vec_int;
string_vector(line,temp_vec);
for(size_t i=1;i<temp_vec.size();++i)
{
    stringstream geek(temp_vec[i]);
    int index=0;
    geek>>index;
    temp_vec_int.push_back(index);
}
Unit_index.emplace(temp_vec[0],temp_vec_int);
}
ifs1.close();
ifstream ifs2;
ifs2.open(Unit_index_path2);
if(!ifs2.is_open())
{
    perror("open Unit_index2");
    return;
}
line.clear();
while(getline(ifs2,line))
{
vector<string>temp_vec;
vector<int>temp_vec_int;
string_vector(line,temp_vec);
for(size_t i=1;i<temp_vec.size();++i)
{
    stringstream geek(temp_vec[i]);
    int index=0;
    geek>>index;
    temp_vec_int.push_back(index);
}
Unit_index.emplace(temp_vec[0],temp_vec_int);
}
ifs2.close();
return ;
}
bool write_webpage(vector<vector<string>>&webpage,Statement *stmt)
{
for(size_t i=0;i<webpage.size();++i)
{
    string sql_str="insert into webpage(doc_id,doc_title,doc_url,doc_content)value";
    sql_str+="(";
    for(size_t y=0;y<webpage[i].size();++y)
    {
        sql_str+="'";
        string_Filter(webpage[i][y]);
        sql_str+=webpage[i][y];
        sql_str+="'";
        if(y!=webpage[i].size()-1)
        sql_str+=",";
    }
    sql_str+=");";
    stmt->execute(sql_str);
}
// cout<<sql_str<<endl;
 
 return true;
}
void write_Word_Index(unordered_map<string,unordered_map<int,double>>&invert_index,Statement* stmt)
{

for(unordered_map<string,unordered_map<int,double>>::iterator it=invert_index.begin();it!=invert_index.end();++it)
{
    string word=it->first;
    unordered_map<int,double> temp=it->second;
    for(unordered_map<int,double>::iterator it2=temp.begin();it2!=temp.end();++it2)
    {
        string sql_str="insert into invertindex(word,doc_id,weight)value";
        sql_str+="('";
        if(word=="\\")
        word="\\\\";
        else if (word=="'") 
        {
            word="''''";
        }
        sql_str+=word;
        sql_str+="',";
        sql_str+=std::to_string(it2->first);
        sql_str+=",'";
        sql_str+=std::to_string(it2->second);
        sql_str+="')";
        sql_str+=";";
       
        stmt->execute(sql_str);
    }

}
}
bool write_Dictionary(unordered_map<string,int>&Dictionary_index)
{
return false;
}
bool write_webpage(unordered_map<string,int>&Unit_index)
{
return false;
} 
bool read_invert_index_sql(vector<string>&query_word,unordered_map<string,set<pair<int,double>>>& _inverIndexTable,Statement *stmt)
{
string sql_str="select word,doc_id,weight from invertindex where ";
for(size_t i=0;i<query_word.size();++i)
{
    sql_str+="word='";
    sql_str+=query_word[i];
    if(i!=query_word.size()-1)
    {
        sql_str+="' or ";
    }
    else sql_str+="';";
}
cout<<sql_str<<endl;
auto res=stmt->executeQuery(sql_str);

while(res->next())
{
string result_word=res->getString("word");
int result_doc_id=res->getInt("doc_id");
double result_weight=res->getDouble("weight");
pair<int,double>temp_pair(result_doc_id,result_weight);
_inverIndexTable[result_word].insert(temp_pair);
}
delete res;
return true;
}
void test01()
{
string webpage_path="../data/ripepage.dat"
,invert_index_path="../data/invertIndex.dat"
,Dictionary_index_path1="../data/ChineseDic"
,Dictionary_index_path2="../data/EnglishDic"
,Unit_index_path1="../data/ChineseIdx"
,Unit_index_path2="../data/EnglishIdx";
//1.将对应的库读入容器中
Driver* driver;
Connection* conn;
Statement *stmt;

driver=get_driver_instance();
conn=driver->connect("tcp://127.0.0.1:3306","root","963258");
conn->setSchema("search_engine");
stmt=conn->createStatement();

//   unordered_map<string,unordered_map<int,double>> invert_index;
//   read_invert_index(invert_index_path,invert_index);
//   write_Word_Index(invert_index,stmt);
vector<string>query_word{"坚决执行","宣战","北京"};
unordered_map<string,set<pair<int,double>>> _inverIndexTable;
read_invert_index_sql(query_word, _inverIndexTable,stmt);
cout<<_inverIndexTable.size()<<endl;
  delete stmt;
  delete conn;
//   unordered_map<string,int> Dictionary_index;
//  read_Dictionary_index(Dictionary_index_path1,Dictionary_index_path2,Dictionary_index);
//  unordered_map<string,vector<int>> Unit_index;
//  read_Unit_index(Unit_index_path1,Unit_index_path2,Unit_index);

//2.遍历容器写入数据库中

}
int main()
{
   test01();
   return EXIT_SUCCESS;
}
